package com.kintreda.tools;


import com.kintreda.tools.utils.JsonMapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CommonUtils {

    /*读取网络文件*/
    public static InputStream getFileInputStream(String path) {
        URL url = null;
        try {
            url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            //设置超时间为3秒
            conn.setConnectTimeout(3*1000);
            //防止屏蔽程序抓取而返回403错误
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            //得到输入流
            return conn.getInputStream();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Object转成JSON数据
     */
    public static String toJson(Object object){
        if(object instanceof Integer || object instanceof Long || object instanceof Float ||
                object instanceof Double || object instanceof Boolean || object instanceof String){
            return String.valueOf(object);
        }
        return JsonMapper.toJson(object);
    }

    /**
     * JSON数据，转成Object
     */
    public static  <T> T fromJson(String json, Class<T> clazz){
        return JsonMapper.fromJson(json, clazz);
    }

    /**
     * 获取对象中的名称和值
     * @param param
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> TreeMap<String,Object> getClassValue(T param, Class<T> clazz) {
        TreeMap<String,Object> ret = new TreeMap<>();
        T t = clazz.cast(param);
        Class<? super T> superclass = clazz.getSuperclass();
        for (Field field1 : superclass.getDeclaredFields()) {
            field1.setAccessible(true);
            try {
                ret.put(field1.getName(),field1.get(t));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        for (Field field : t.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            /** 过滤静态属性**/
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            /** 过滤transient 关键字修饰的属性**/
            if (Modifier.isTransient(field.getModifiers())) {
                continue;
            }
            try {
                ret.put(field.getName(),field.get(t));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        return ret;
    }


    /**
     * 获取文件后缀名
     * @param name
     * @return
     */
    public static String getSuffix(String name){
        // 判断是否是合法的文件后缀
        int dotPos = name.lastIndexOf(".");
        if (dotPos < 0) {
            return null;
        }
        return name.substring(dotPos + 1).toLowerCase();
    }

    /**
     * 生成订单号
     * @param begin 电子票订单：P,商品订单：C,S：水站下单
     * @return
     */
    public static String getOrderIdByTime(String begin) {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
        String newDate=sdf.format(new Date());
        String result="";
        Random random=new Random();
        for(int i=0;i<3;i++){
            result+=random.nextInt(10);
        }
        return begin+newDate+result;
    }

    /**
     * 生成下单批次号
     * @param userId
     * @return
     */
    public static String getOrderBatch(Long userId) {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
        String newDate=sdf.format(new Date());
        return "U"+newDate+""+userId;
    }

    /**
     * 密码加密函数
     * @param pwd
     * @return
     */
    public static String getPwd(String pwd){
        return new BCryptPasswordEncoder().encode(pwd);
    }


    /**
     * 手机号验证
     * @param phone
     * @return
     */
    public static boolean isMobile(String phone) {
        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
        if (phone.length() != 11) {
            return false;
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            if (!isMatch) {
                return false;
            }
            return isMatch;
        }
    }


    /**
     * 生成随机字符串
     * @param length
     * @return
     */
    public static String getRandomString(int length){
        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        for(int i=0;i<length;i++){
            int number=random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 生成随机整数
     * @param length
     * @return
     */
    public static Integer getRandomNum(int length){
        StringBuffer sb = new StringBuffer();
        Random r = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(r.nextInt(10));
        }
        int num = Integer.parseInt(sb.toString());
        if (num<0){
            return getRandomNum(length);
        }else{
            return num;
        }
    }


    /**
     * sha1加密
     * @param str
     * @return
     */
    public static String getSha1(String str) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f' };
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));
            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取md5值
     * @param value
     * @return
     */
    public static String getMd5(String value){
        try {
            //1. 获得md5加密算法工具类
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            //2. 加密的结果为十进制
            byte[] md5Bytes = messageDigest.digest(value.getBytes());
            //3. 将md5加密算法值转化为16进制
            BigInteger bigInteger = new BigInteger(1, md5Bytes);
            return bigInteger.toString(16);
        } catch (Exception e) {
            //如果产生错误则抛出异常
            throw new RuntimeException();
        }
    }



    /**
     * 将时间戳转换为时间
     * @param s
     * @return
     * @throws Exception
     */
    public static String stampToTime(String s) throws Exception{
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        //将时间戳转换为时间
        Date date = new Date(lt);
        //将时间调整为yyyy-MM-dd HH:mm:ss时间样式
        res = simpleDateFormat.format(date);
        return res;
    }
}
